import { isObj } from '@king-one/utils'
import dayjs from 'dayjs'

export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
  let key: string
  for (key in target) {
    src[key] = isObj(src[key])
      ? deepMerge(src[key], target[key])
      : (src[key] = target[key])
  }
  return src
}
export function parseFormString(formString: string): BasicObject<string> {
  const formArr: Array<string> = formString.split(/\s*;\s*/)

  const formObj = formArr.reduce((init: BasicObject<string>, item) => {
    const [key, value] = item.split('=')

    init[key] = (value || '').replace(/^"|"$/g, '')

    return init
  }, {})

  return formObj
}

export function randomKey() {
  return (new Date().valueOf() + Math.ceil(Math.random() * 10000)).toString()
    + Math.random().toString(16).substring(2, 15)
}

export function handleFn<T extends (...args: any) => any>(fn: T | undefined | null, ...args: Parameters<T>) {
  return (typeof fn === 'function' ? fn(...(args as any)) : undefined) as ReturnType<T>
}

export function base64ToBlob(base64: string, onsuccess?: any, onerror?: any) {
  const img = new Image()

  img.onerror = onerror

  img.onload = function onload() {
    const canvas = document.createElement('canvas')
    canvas.width = img.width
    canvas.height = img.height

    const ctx = canvas.getContext('2d')!
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

    canvas.toBlob((blobData: any) => {
      const blobUrl = URL.createObjectURL(blobData)

      onsuccess(blobUrl)
    })
  }

  img.src = base64
}

type StorageType = 'sessionStorage' | 'localStorage'

export function saveToStorage(
  obj: Record<string, any>,
  storageType: StorageType = 'sessionStorage',
) {
  Object.keys(obj).forEach((key) => {
    window[storageType].setItem(key, obj[key])
  })
}

export function getFromStorage(
  key: string,
  storageType?: StorageType
): string | null
export function getFromStorage(
  key: string[],
  storageType?: StorageType
): (string | null)[]
export function getFromStorage(
  key: string | string[],
  storageType: StorageType = 'sessionStorage',
) {
  if (typeof key === 'string') {
    return window[storageType].getItem(key) || null
  }

  return key.map(k => window[storageType].getItem(k) || null)
}

export function dateTimeFormat(date?: string | number | Date | dayjs.Dayjs | null | 'now', formatStr: string = 'YYYY-MM-DD', placeholder: string = '-'): string {
  if (!date) {
    return placeholder
  }

  return dayjs(date === 'now' ? undefined : date).format(formatStr)
}

export function delay(ms = 10) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}
